package com.base.component.app.apple;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;

import org.apache.commons.codec.binary.Base64;

import com.gitee.magic.core.exception.ApplicationException;
import com.gitee.magic.core.json.JsonArray;
import com.gitee.magic.core.json.JsonObject;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;

/**
 * 苹果登录
 * @author mac
 *
 */
public class AppleLogin {
	
    public boolean verify(String identityToken) {
        try {
            if (identityToken.split("\\.").length > 1){
                String firstDate = new String(Base64.decodeBase64(identityToken.split("\\.")[0]),"UTF-8");
                String claim = new String(Base64.decodeBase64(identityToken.split("\\.")[1]), "UTF-8");
                String kid = new JsonObject(firstDate).get("kid").toString();
                String aud = new JsonObject(claim).get("aud").toString();
                String sub = new JsonObject(claim).get("sub").toString();
                PublicKey publicKey = getPublicKey(kid);
                if (publicKey == null) {
                    return false;
                }
                return verify(publicKey, identityToken, aud, sub);
            }
        } catch (Exception e) {
        	throw new ApplicationException(e);
        }
        return false;
    }

    private boolean verify(PublicKey key, String jwt, String audience, String subject){
        boolean result = false;
        JwtParser jwtParser = Jwts.parser().setSigningKey(key);
        jwtParser.requireIssuer("https://appleid.apple.com");
        jwtParser.requireAudience(audience);
        jwtParser.requireSubject(subject);
        try {
            Jws<Claims> claim = jwtParser.parseClaimsJws(jwt);
            if (claim != null && claim.getBody().containsKey("auth_time")) {
                return true;
            }
        } catch (ExpiredJwtException e) {
        	throw new ApplicationException(e);
        }
        return result;
    }

    private PublicKey getPublicKey(String kid) {
    	JsonObject jsonKeys=new JsonObject(AppleApi.authKeys());
        JsonArray jsonArray =jsonKeys.getJsonArray("keys");
        for(int i=0;i<jsonArray.length();i++) {
        	JsonObject json = jsonArray.getJsonObject(i);
            if (json.getString("kid").equals(kid)) {
                String n = json.getString("n");
                String e = json.getString("e");
                BigInteger modulus = new BigInteger(1, Base64.decodeBase64(n));
                BigInteger publicExponent = new BigInteger(1, Base64.decodeBase64(e));
                RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, publicExponent);
				try {
					KeyFactory kf = KeyFactory.getInstance("RSA");
	                return kf.generatePublic(spec);
				} catch (NoSuchAlgorithmException | InvalidKeySpecException e1) {
					throw new ApplicationException(e1);
				}
            }
        }
        return null;
    }
    
    public static void main(String[] args) {
    	AppleLogin a=new AppleLogin();
//    	System.out.println(a.getHttp(APPLE_AUTH_URL));
//    	RestTemplate restTemplate = new RestTemplate();
//        JsonObject json = restTemplate.getForObject(APPLE_AUTH_URL, JsonObject.class);
//        System.out.println(json);
//    	HttpRequest request=new HttpRequest(APPLE_AUTH_URL,RequestMethodEnum.GET);
//    	HttpWrapper wrapper=new HttpWrapper();
//    	System.out.println(wrapper.start(request));
//    	System.out.println(a.getPublicKey("T8tIJ1zSrO"));
    	String token="eyJraWQiOiJGZnRPTlR4b0VnIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoiY24uYWJ1eWF3LmFwcCIsImV4cCI6MTcyNzQwODMwMSwiaWF0IjoxNzI3MzIxOTAxLCJzdWIiOiIwMDAyMzcuOTMzNTM0ZTIzZTgwNGUzNWJkMTQzY2FiNjNjOWQ3ZjIuMDk0MiIsImNfaGFzaCI6IktXa2tyWGZaejVNTEpBSllXRjgzeHciLCJlbWFpbCI6Ims3Z21uZDJucnFAcHJpdmF0ZXJlbGF5LmFwcGxlaWQuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzX3ByaXZhdGVfZW1haWwiOnRydWUsImF1dGhfdGltZSI6MTcyNzMyMTkwMSwibm9uY2Vfc3VwcG9ydGVkIjp0cnVlfQ.I8BUwdojoXcPfQtBfv_hiwMMJUk_uyisHSxx5YJcX1GvPXqwCg-KAf0vX5Z9eEaCYLtfHKx1f_B2BLtBOMy8wr8lncUa2QriedTmRPsgRjCeZHHqVjuYkM2_QrKotVLNriKnf0T_dqLLciAbufKrNYPYu-l6qqHKothhKz1YwHmao7a5FW5RPJkJguMsGKjDxY7sEVvmfPeTFx7ECQW-iuGuA_u8zHO3Z84XmgiuMDxeWzsG69VZmU3TdLysSEgGn_NulOw3qlXV_aE7HZcxvni6TVuULN0-uJg-a1x5EFeS-Do_5jqyp5NJEg--IYzKHeJP9EJJ9GT51PjaUQAWDA";
    	if(a.verify(token)) {
    		try {
				String claim = new String(Base64.decodeBase64(token.split("\\.")[1]), "UTF-8");
				System.out.println(claim);
			} catch (UnsupportedEncodingException e) {
				throw new ApplicationException(e);
			}
    	}
	}
    
}
